package com.zf.yichat.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zf.yichat.config.utils.GoogleAuthenticationToolUtils;
import com.zf.yichat.config.utils.RedisUtil;
import com.zf.yichat.controller.verification.VerifyGoogleCodeController;
import com.zf.yichat.dto.UserRoleSelectCondition;
import com.zf.yichat.mapper.RegisterAutoMapper;
import com.zf.yichat.model.RcGroups;
import com.zf.yichat.model.RegisterAuto;
import com.zf.yichat.model.SysUser;
import com.zf.yichat.model.User;
import com.zf.yichat.service.BalanceService;
import com.zf.yichat.service.GroupService;
import com.zf.yichat.service.SysUserService;
import com.zf.yichat.service.UserService;
import com.zf.yichat.service.common.shiro.helper.AdminPasswordHelper;
import com.zf.yichat.utils.common.FsConst;
import com.zf.yichat.utils.common.OKHttpUtil;
import com.zf.yichat.utils.response.FsResponse;
import com.zf.yichat.utils.response.FsResponseGen;
import com.zf.yichat.vo.UserRoleEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.internal.util.Contracts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Controller
@Slf4j
public class LoginController extends BaseController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private UserService userService;
    @Autowired
    private BalanceService balanceService;

    @Resource
    private RegisterAutoMapper registerAutoMapper;

    @Resource
    private GroupService groupService;

    @Autowired
    private RedisUtil redisUtil;

    @Resource
    private AdminPasswordHelper passwordHelper;

    @Value("${st.im_uri}")
    private String imUri;
    /**
     * 用户管理-批量注册功能
     * @param password
     * @param payPassword
     * @param phone
     * @param count
     * @param isFriend
     * @param isNewGroup
     * @param groupId
     * @return
     */
    @RequestMapping({"/registerAuto/save"})
    @ResponseBody
    public FsResponse register(String password, String payPassword, Long phone, Integer count, Boolean isFriend, Boolean isNewGroup, Integer groupId,String recommendCode) {
        Contracts.assertNotNull(password);
        Contracts.assertNotNull(payPassword);
        Contracts.assertNotNull(count);
        Contracts.assertNotNull(phone);

        if (Objects.nonNull(groupId)) {
            RcGroups groups = groupService.selectById(groupId);
            if (Objects.isNull(groups)) {
                return FsResponseGen.failMsg("群id错误");
            }
        }
        if (count>20) {
                return FsResponseGen.failMsg("单次最多创建20个账号");
        }


        ClassPathResource classPathResource = new ClassPathResource("nickname.json");
        StringBuilder sb = new StringBuilder();
        try {
            InputStream is = classPathResource.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            String data;
            while ((data = br.readLine()) != null) {
                sb.append(data);
            }

            br.close();
            isr.close();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


        JSONArray jsonArray;
        if (sb.length() > 0) {
            jsonArray = JSON.parseArray(sb.toString());
        } else {
            return FsResponseGen.failMsg("获取昵称失败");
        }

        Integer totalCount = registerAutoMapper.sumTotalCount();
        if (totalCount == null) {
            totalCount = 0;
        }
        int startIndex = totalCount + 1;

        StringBuilder resultMsg = new StringBuilder();
        List<Long> ids = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int currentIndex = (startIndex + i) % 2000;
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("nickname", jsonArray.getString(currentIndex));
            jsonObject.put("phone", phone.toString());
            jsonObject.put("platform", "1");
            jsonObject.put("region", "86");
            jsonObject.put("password", password);
            jsonObject.put("deviceId", phone.toString());
            jsonObject.put("clientIp", "127.0.0.1");
            if (StringUtils.isBlank(recommendCode)) {
                jsonObject.put("recommendCode","235b2g4824dxs");
            }
            else {
                jsonObject.put("recommendCode","a1d2m3i4n5|" + recommendCode);
            }
            jsonObject.put("verification_token", "239tNGUIJA@&#(nkgj93HFKUW9jfewtewnbu83w98FNSNUEIFCGDSOWEOEIW23N,|GFNDSLOJG");
            String result = OKHttpUtil.httpPostJson(imUri + "user/register", jsonObject.toJSONString());
            if (Objects.isNull(result)) {
                resultMsg.append(phone).append("、");
            } else {
                try {
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getInteger("code") != 200) {
                        resultMsg.append(phone).append("、");
                    } else {
                        //设置实名认证和支付密码
                        try {
                            User user = userService.selectByMobile(phone.toString());
                            ids.add(user.getId());
                            user.setRealStatus(1);
                            user.setRealName(String.valueOf(user.getId()));
                            user.setIdNumber(String.valueOf(user.getId()));
                            // 使用MD5加密密码
                          //  user.setPassword(MD5Util.string2MD5(user.getPassword()));
                            userService.update(user);
                            //  更新支付密码
                            balanceService.updatePassword(user.getId(), payPassword);

                        } catch (Exception e) {
                            e.printStackTrace();
                            resultMsg.append(phone).append("实名失败、");
                        }
                    }
                } catch (Exception e) {
                    resultMsg.append(phone).append("、");
                }
            }
            phone = phone + 1;
        }
        if (resultMsg.length() > 0) {
            resultMsg.append("注册失败\n");
        }

        if (resultMsg.length() == 0) {
            resultMsg.append("注册全部成功\n");
        }

        if (isFriend) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("description", "ghslagds2392s");
            jsonObject.put("friendIdList", ids);
            String result = OKHttpUtil.httpPostJson(imUri + "friendship/agree_by_admin", jsonObject.toJSONString());
            if (Objects.isNull(result)) {
                resultMsg.append("互为好友失败，8081异常\n");
            } else {
                try {
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getInteger("code") != 200) {
                        resultMsg.append("互为好友全部失败\n");
                    } else {
                        resultMsg.append(StringUtils.isEmpty(resJson.getString("result")) ? "互为好友全部成功\n" : resJson.getString("result"));
                    }
                } catch (Exception e) {
                    resultMsg.append("互为好友全部异常\n");
                }
            }
        }

        if (Objects.nonNull(groupId)) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("portraitUri", "ghslagds2392s");
            jsonObject.put("memberIdList", ids);
            jsonObject.put("groupId", groupId);
            String result = OKHttpUtil.httpPostJson(imUri + "group/add_by_admin", jsonObject.toJSONString());
            if (Objects.isNull(result)) {
                resultMsg.append("加群失败，8081异常\n");
            } else {
                try {
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getInteger("code") != 200) {
                        resultMsg.append("加群失败\n");
                    } else {
                        resultMsg.append("加群成功");
                    }
                } catch (Exception e) {
                    resultMsg.append("加群异常\n");
                }
            }
        }
        RegisterAuto registerAuto = new RegisterAuto();
        registerAuto.setCount(count);
        registerAuto.setPhone(phone);
        registerAuto.setCtime(new Date());
        registerAuto.setGroupid(groupId);
        registerAuto.setIsfriend(isFriend ? 1 : 0);
        registerAuto.setIsnewgroup(isNewGroup ? 1 : 0);
        registerAuto.setPassword(password);
        registerAuto.setResult(resultMsg.toString());
        registerAutoMapper.insert(registerAuto);

        return FsResponseGen.successData(resultMsg.toString());
    }

    @RequestMapping({"/registerAuto/index"})
    public String registerXHIndex() {
        RegisterAuto registerAuto = registerAutoMapper.selectLastRegister();
        getRequest().setAttribute("registerAuto", registerAuto);
        return "member/register/save";
    }

    /**
     * 后台管理系统-登录页面
     * @return
     */
    @RequestMapping("/login")
    public String index() {
//        try {
//
//            RSAPublicKey publicKey = RsaUtilWeb.getPublicKey(PUBLIC_PATH);
//            String modules = publicKey.getModulus().toString(16);
//            String publicExponent = publicKey.getPublicExponent().toString(16);
//            getRequest().setAttribute("modules", modules);
//            getRequest().setAttribute("publicExponent", publicExponent);
//        } catch (Exception e) {
//            log.error("获取密码公钥错误", e);
//            return "login/login";
//        }
        return "login/login";
    }

    /**
     * 管理系统-登录方法
     * @param username
     * @param password
     * @param twoFactorCode
     * @param request
     * @return
     */
    @RequestMapping("/login/valid/user")
    @ResponseBody
    public FsResponse validUser(String username, String password, String twoFactorCode, HttpServletRequest request) {

        //密码解密
//        password = super.passwordDecrypt(password);
//        if(StringUtils.isEmpty(password)) {
//            return FsResponseGen.failMsg("系统错误：Decrypt Err");
//        }

        SysUser user = sysUserService.selectUserByUsername(username);
        boolean passwordCorrect = passwordHelper.testingPassword(user.getSalt(), user.getPassword(),password, user.getUsername());

        // 更新数据库中已有的明文密码
        if (Objects.isNull(user) || !passwordCorrect) {
            if (!user.getPassword().equals(password)) {
                return FsResponseGen.fail();
            }

            // 明文相等，需要更新数据库中的明文密码

            SysUser updateSecret = new SysUser();
            updateSecret.setId(user.getId());
            updateSecret.setPassword(password);
            updateSecret.setUsername(username);

            // 更新密码为密文
            passwordHelper.encryptPassword(updateSecret);
            sysUserService.update(updateSecret);

        }

        // 查看是否生成谷歌验证器的KEY值, 没有生成时代表管理员还没绑定
        String key = (String) redisUtil.get(VerifyGoogleCodeController.RANDOM_SECRET_KEY + "_" + username);
        if (StringUtils.isBlank(key)) {

            HttpSession session = request.getSession();
            session.setAttribute("isOperate", true);
            session.setAttribute("user", user);
            UserRoleSelectCondition condition = sysUserService.genCondition(user.getId());
            session.setAttribute("isAdmin", UserRoleEnum.ADMIN.compareTo(condition.getRole()) == 0);
            return FsResponseGen.success();
        }

        // 登录者都需要验证谷歌身份验证
        String googleVerifyState = user.getGoogleVerifyState();
        if (StringUtils.isNotBlank(googleVerifyState) && googleVerifyState.equals("0")) {
            if (StringUtils.isBlank(twoFactorCode)) {
                return FsResponseGen.fail(FsConst.ResponseCode.TWO_FACTOR_CODE_FAIL, "请输入Google身份验证码");
            }

            long time = System.currentTimeMillis ();
            GoogleAuthenticationToolUtils g = new GoogleAuthenticationToolUtils ();


            if(StringUtils.isBlank(key)){
                return FsResponseGen.fail(FsConst.ResponseCode.TWO_FACTOR_KEY_EXPIRE, "Google身份验证器KEY失效，请联系管理员");
            }


            if (!isNumeric(twoFactorCode)) {
                return FsResponseGen.failMsg("Google身份验证码格式不正确");
            }

            Long code = Long.valueOf(twoFactorCode);
            boolean result = g.check_code (key, code, time);
            if (!result) {
                return FsResponseGen.fail(FsConst.ResponseCode.TWO_FACTOR_CODE_FAIL, "Google身份验证码不正确");
            }
        }

        HttpSession session = request.getSession();
        session.setAttribute("isOperate", true);
        session.setAttribute("user", user);
        UserRoleSelectCondition condition = sysUserService.genCondition(user.getId());
        session.setAttribute("isAdmin", UserRoleEnum.ADMIN.compareTo(condition.getRole()) == 0);

        return FsResponseGen.success();
    }

    public static boolean isNumeric(String str) {
        return str.matches("\\d+");
    }

    /**
     * 用户退出
     */
    @RequestMapping(value = "/logout")
    public String logout() {

        HttpSession session = getRequest().getSession();
        if (session != null) {
            session.setAttribute(session.getId(), null);
            session.setAttribute("user", null);
        }

        return "login/login";

    }


    @RequestMapping("/login/online")
    public String onlineIndex() {
        return "login/online";
    }

}
